// SessionSocket.cpp : implementation file
//

#include "stdafx.h"
#include "SessionSocket.h"
#include "SessionLink.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSessionSocket

CSessionSocket::CSessionSocket()
{
	InitMember();
}

CSessionSocket::CSessionSocket(CSessionLink* pSessionLink)
{
	InitMember();
	m_pSessionLink = pSessionLink;
}

CSessionSocket::~CSessionSocket()
{

}

void CSessionSocket::InitMember()
{
	m_pSessionLink = NULL;
	m_dwSocketState = SOCKET_LINK_STATE_INIT;
}

// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CSessionSocket, CAsyncSocket)
	//{{AFX_MSG_MAP(CSessionSocket)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0

/////////////////////////////////////////////////////////////////////////////
// CSessionSocket member functions

void CSessionSocket::OnClose(int nErrorCode) 
{
	SetSocketLinkState(SOCKET_LINK_STATE_DEATH);
	if(m_pSessionLink)
	{
		m_pSessionLink->OnSessionEnd(nErrorCode);
	}
	else
	{
		CloseSocket();
	}
}

void CSessionSocket::OnConnect(int nErrorCode) 
{
	if(nErrorCode == 0)
	{
		SetSocketLinkState(SOCKET_LINK_STATE_AVAILABLE);
	}
	if(m_pSessionLink)
	{
		m_pSessionLink->OnConnected(nErrorCode);
	}
	else
	{
		CloseSocket();
	}
}

void CSessionSocket::OnReceive(int nErrorCode) 
{
	if(m_pSessionLink)
	{
		m_pSessionLink->OnReceiveData();
	}	
	else
	{
		CloseSocket();
	}
}

void CSessionSocket::OnSend(int nErrorCode) 
{
	if(m_pSessionLink)
	{
		m_pSessionLink->OnSendData();
	}	
	else
	{
		CloseSocket();
	}
}

void CSessionSocket::ClearSession()
{
	m_pSessionLink = NULL;
}

void CSessionSocket::CloseSocket()
{
	SetSocketLinkState(SOCKET_LINK_STATE_DEATH);
	if (m_hSocket != INVALID_SOCKET)
	{			
		AsyncSelect(0);
		LINGER lingerStruct;
		lingerStruct.l_onoff = 1;
		lingerStruct.l_linger = 0;
		SetSockOpt(SO_LINGER, (char *)&lingerStruct, sizeof(lingerStruct));
		Close();
	}
	if(IsAutoDelete())
	{
		delete this;
	}
}

void CSessionSocket::SetSocketLinkState(DWORD dwLinkState)
{
	::SetOptions(m_dwSocketState,dwLinkState,SOCKET_LINK_STATE_MASK);
}

DWORD CSessionSocket::GetSocketLinkState()
{
	return ::GetOptions(m_dwSocketState,SOCKET_LINK_STATE_MASK);
}

void CSessionSocket::IncreaseTimeCount()
{
	m_dwSocketState ++;
}

DWORD CSessionSocket::GetTimeCount()
{
	return ::GetOptions(m_dwSocketState,SOCKET_TIME_COUNT_MASK);
}

void CSessionSocket::RestTimeCount()
{
	::SetOptions(m_dwSocketState,0,SOCKET_TIME_COUNT_MASK);
}

BOOL CSessionSocket::IsAutoDelete()
{
	return (::GetOptions(m_dwSocketState,SOCKET_OPTION_AUTO_DELETE));
}

void CSessionSocket::EnableAutoDelete(BOOL bEnable)
{
	if(bEnable)
	{
		::SetOptions(m_dwSocketState,SOCKET_OPTION_AUTO_DELETE,SOCKET_OPTION_AUTO_DELETE);
	}
	else
	{
		::SetOptions(m_dwSocketState,0,SOCKET_OPTION_AUTO_DELETE);
	}
}
